package com.example.videopublish.service

import android.accessibilityservice.AccessibilityService
import android.accessibilityservice.GestureDescription
import android.content.Intent
import android.graphics.Path
import android.graphics.Rect
import android.net.Uri
import android.os.Handler
import android.os.Looper
import android.view.accessibility.AccessibilityEvent
import android.view.accessibility.AccessibilityNodeInfo
import android.widget.Toast
import java.util.concurrent.ConcurrentLinkedQueue
import kotlin.random.Random

/**
 * 抖音RPA服务
 * 通过无障碍服务实现对抖音应用的自动化操作，完成视频发布
 */
class DouyinRpaService : AccessibilityService() {

    companion object {
        // 动作常量
        const val ACTION_PUBLISH = "com.example.videopublish.action.PUBLISH"
        
        // Intent参数键
        const val EXTRA_VIDEO_URI = "extra_video_uri"
        const val EXTRA_VIDEO_TITLE = "extra_video_title"
        const val EXTRA_VIDEO_DESCRIPTION = "extra_video_description"
        const val EXTRA_VIDEO_TAGS = "extra_video_tags"
        
        // 抖音包名
        private const val DOUYIN_PACKAGE_NAME = "com.ss.android.ugc.aweme"
        
        // RPA步骤超时时间（毫秒）
        private const val STEP_TIMEOUT = 10000L
    }
    
    // RPA操作步骤枚举
    private enum class RpaStep {
        IDLE,                // 空闲状态
        LAUNCH_DOUYIN,       // 启动抖音
        OPEN_PUBLISH_PAGE,   // 打开发布页面
        SELECT_VIDEO,        // 选择视频
        FILL_INFO,           // 填写信息
        SUBMIT,              // 提交发布
        CONFIRM,             // 确认发布
        WAIT_RESULT,         // 等待结果
        COMPLETE,            // 完成
        ERROR                // 错误
    }
    
    // 当前RPA操作状态
    private var currentStep = RpaStep.IDLE
    
    // 视频发布参数
    private var videoUri: Uri? = null
    private var videoTitle: String = ""
    private var videoDescription: String = ""
    private var videoTags: String = ""
    
    // 步骤超时处理
    private val handler = Handler(Looper.getMainLooper())
    private val stepTimeoutRunnable = Runnable {
        if (currentStep != RpaStep.IDLE && currentStep != RpaStep.COMPLETE && currentStep != RpaStep.ERROR) {
            handleStepTimeout()
        }
    }
    
    // 操作队列
    private val operationQueue = ConcurrentLinkedQueue<() -> Unit>()
    private var isProcessingQueue = false

    /**
     * 处理启动命令
     */
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        intent?.let {
            if (ACTION_PUBLISH == it.action) {
                // 解析视频发布参数
                val videoUriString = it.getStringExtra(EXTRA_VIDEO_URI)
                videoUri = if (videoUriString != null) Uri.parse(videoUriString) else null
                videoTitle = it.getStringExtra(EXTRA_VIDEO_TITLE) ?: ""
                videoDescription = it.getStringExtra(EXTRA_VIDEO_DESCRIPTION) ?: ""
                videoTags = it.getStringExtra(EXTRA_VIDEO_TAGS) ?: ""
                
                if (videoUri != null) {
                    // 开始RPA流程
                    startPublishProcess()
                } else {
                    showToast("无效的视频URI")
                }
            }
        }
        return super.onStartCommand(intent, flags, startId)
    }

    /**
     * 处理无障碍事件
     */
    override fun onAccessibilityEvent(event: AccessibilityEvent) {
        if (currentStep == RpaStep.IDLE || currentStep == RpaStep.COMPLETE || currentStep == RpaStep.ERROR) {
            return
        }
        
        try {
            when (currentStep) {
                RpaStep.LAUNCH_DOUYIN -> handleLaunchDouyin(event)
                RpaStep.OPEN_PUBLISH_PAGE -> handleOpenPublishPage(event)
                RpaStep.SELECT_VIDEO -> handleSelectVideo(event)
                RpaStep.FILL_INFO -> handleFillInfo(event)
                RpaStep.SUBMIT -> handleSubmit(event)
                RpaStep.CONFIRM -> handleConfirm(event)
                RpaStep.WAIT_RESULT -> handleWaitResult(event)
                else -> {}
            }
        } catch (e: Exception) {
            e.printStackTrace()
            updateStep(RpaStep.ERROR)
            showToast("发布过程出错: ${e.message}")
        }
    }

    /**
     * 处理连接服务事件
     */
    override fun onServiceConnected() {
        super.onServiceConnected()
        showToast("视频发布服务已启用")
    }

    /**
     * 开始视频发布流程
     */
    private fun startPublishProcess() {
        // 复位所有状态
        operationQueue.clear()
        isProcessingQueue = false
        
        // 更新步骤为启动抖音
        updateStep(RpaStep.LAUNCH_DOUYIN)
        
        // 创建启动抖音的Intent
        val launchDouyinIntent = packageManager.getLaunchIntentForPackage(DOUYIN_PACKAGE_NAME)
        if (launchDouyinIntent != null) {
            launchDouyinIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            startActivity(launchDouyinIntent)
        } else {
            showToast("未安装抖音应用")
            updateStep(RpaStep.ERROR)
        }
    }

    /**
     * 处理启动抖音应用步骤
     */
    private fun handleLaunchDouyin(event: AccessibilityEvent) {
        // 检查我们是否已在抖音应用中
        if (event.packageName == DOUYIN_PACKAGE_NAME) {
            // 等待主页加载完成
            if (findNodeByDescription("首页") != null || findNodeByDescription("我") != null) {
                // 更新步骤为打开发布页面
                updateStep(RpaStep.OPEN_PUBLISH_PAGE)
            }
        }
    }

    /**
     * 处理打开发布页面步骤
     */
    private fun handleOpenPublishPage(event: AccessibilityEvent) {
        // 查找并点击发布按钮（通常在底部导航栏中）
        val publishNode = findNodeByDescription("发布")
            ?: findNodeByText("发布")
            ?: findNodeWithId("com.ss.android.ugc.aweme:id/bqs") // 可能的ID，实际使用时需要确认
        
        if (publishNode != null) {
            // 模拟点击发布按钮
            simulateHumanClick(publishNode)
            // 更新步骤为选择视频
            updateStepWithDelay(RpaStep.SELECT_VIDEO, 1500)
        }
    }

    /**
     * 处理选择视频步骤
     */
    private fun handleSelectVideo(event: AccessibilityEvent) {
        // 在抖音的选择视频界面，查找相册或视频选择入口
        val galleryNode = findNodeByText("相册") 
            ?: findNodeByText("从手机相册选择")
            ?: findNodeByDescription("相册")
        
        if (galleryNode != null) {
            // 模拟点击相册按钮
            simulateHumanClick(galleryNode)
            // 由于我们无法直接在系统相册中通过RPA选择指定视频，
            // 这里可能需要用户手动选择。
            // 在实际产品中，可以考虑：
            // 1. 使用系统的文件选择器Intent
            // 2. 预先准备好要发布的视频文件名，引导用户选择
            
            // 为了演示，我们假设用户会手动选择视频，然后更新为下一步
            showToast("请在相册中选择您想发布的视频")
            // 在实际产品中，我们需要等待用户选择完视频后的界面变化
            // 此处假设用户已选择，稍后会进入编辑信息界面
            updateStepWithDelay(RpaStep.FILL_INFO, 5000)
        }
    }

    /**
     * 处理填写视频信息步骤
     */
    private fun handleFillInfo(event: AccessibilityEvent) {
        // 检查是否已经进入编辑界面
        val captionField = findNodeByHint("添加描述...")
            ?: findNodeByHint("添加标题...")
            ?: findEditTextNodes().firstOrNull()
        
        if (captionField != null) {
            // 构建要填写的文本内容
            val captionText = buildCaptionText()
            
            // 延迟队列执行，模拟人工操作
            queueOperation {
                // 填写标题/描述
                captionField.performAction(AccessibilityNodeInfo.ACTION_FOCUS)
                captionField.performAction(AccessibilityNodeInfo.ACTION_SET_TEXT, captionText)
            }
            
            // 更新步骤为提交
            updateStepWithDelay(RpaStep.SUBMIT, 2000)
        }
    }

    /**
     * 处理提交发布步骤
     */
    private fun handleSubmit(event: AccessibilityEvent) {
        // 查找发布按钮
        val publishButton = findNodeByText("发布")
            ?: findNodeByText("完成")
            ?: findNodeByDescription("发布")
        
        if (publishButton != null) {
            // 模拟点击发布按钮
            simulateHumanClick(publishButton)
            // 更新步骤为确认发布（如果需要）
            updateStepWithDelay(RpaStep.CONFIRM, 1500)
        }
    }

    /**
     * 处理确认发布步骤（处理可能出现的对话框）
     */
    private fun handleConfirm(event: AccessibilityEvent) {
        // 查找确认对话框中的确认按钮
        val confirmButton = findNodeByText("确定")
            ?: findNodeByText("确认")
            ?: findNodeByText("发布")
        
        if (confirmButton != null) {
            // 模拟点击确认按钮
            simulateHumanClick(confirmButton)
        }
        
        // 无论有没有确认对话框，都进入等待结果状态
        updateStepWithDelay(RpaStep.WAIT_RESULT, 1000)
    }

    /**
     * 处理等待发布结果步骤
     */
    private fun handleWaitResult(event: AccessibilityEvent) {
        // 查找发布成功的提示
        val successNode = findNodeByText("发布成功")
            ?: findNodeByText("已发布")
            ?: findNodeByDescription("发布成功")
        
        if (successNode != null) {
            // 发布成功
            showToast("视频已成功发布到抖音")
            updateStep(RpaStep.COMPLETE)
            return
        }
        
        // 检查是否仍在发布中
        val publishingNode = findNodeByText("发布中")
            ?: findNodeByText("正在发布")
            ?: findNodeByDescription("正在发布")
        
        if (publishingNode != null) {
            // 继续等待
            return
        }
        
        // 如果既没有成功提示也没有正在发布提示，可能已经完成或失败
        // 为了保险起见，我们设置一个最大等待时间
        // 此逻辑在步骤超时处理中
    }

    /**
     * 处理步骤超时
     */
    private fun handleStepTimeout() {
        when (currentStep) {
            RpaStep.WAIT_RESULT -> {
                // 等待结果超时，假设发布成功
                showToast("假设视频已成功发布")
                updateStep(RpaStep.COMPLETE)
            }
            else -> {
                // 其他步骤超时，视为错误
                showToast("操作超时，请重试")
                updateStep(RpaStep.ERROR)
            }
        }
    }

    /**
     * 更新当前RPA步骤
     */
    private fun updateStep(step: RpaStep) {
        // 取消之前的超时计时
        handler.removeCallbacks(stepTimeoutRunnable)
        
        // 更新当前步骤
        currentStep = step
        
        // 如果是终止状态，清空操作队列
        if (step == RpaStep.COMPLETE || step == RpaStep.ERROR || step == RpaStep.IDLE) {
            operationQueue.clear()
            isProcessingQueue = false
            return
        }
        
        // 设置新的超时计时
        handler.postDelayed(stepTimeoutRunnable, STEP_TIMEOUT)
    }

    /**
     * 延迟后更新步骤
     */
    private fun updateStepWithDelay(step: RpaStep, delayMs: Long) {
        handler.postDelayed({
            updateStep(step)
        }, delayMs)
    }

    /**
     * 添加操作到队列
     */
    private fun queueOperation(operation: () -> Unit) {
        operationQueue.add(operation)
        
        if (!isProcessingQueue) {
            processOperationQueue()
        }
    }

    /**
     * 处理操作队列
     */
    private fun processOperationQueue() {
        if (operationQueue.isEmpty()) {
            isProcessingQueue = false
            return
        }
        
        isProcessingQueue = true
        
        // 获取队列中的下一个操作
        val operation = operationQueue.poll() ?: return
        
        // 延迟随机时间后执行，模拟人工操作
        handler.postDelayed({
            operation.invoke()
            
            // 继续处理队列
            processOperationQueue()
        }, getRandomDelay())
    }

    /**
     * 模拟真实用户点击
     */
    private fun simulateHumanClick(node: AccessibilityNodeInfo) {
        if (node.isClickable) {
            // 使用原生点击如果节点可点击
            queueOperation {
                node.performAction(AccessibilityNodeInfo.ACTION_CLICK)
            }
        } else {
            // 否则使用手势模拟点击
            val rect = Rect()
            node.getBoundsInScreen(rect)
            
            val centerX = rect.centerX().toFloat()
            val centerY = rect.centerY().toFloat()
            
            // 添加轻微偏移，模拟真实点击
            val offsetX = Random.nextInt(-10, 10)
            val offsetY = Random.nextInt(-10, 10)
            
            val clickX = centerX + offsetX
            val clickY = centerY + offsetY
            
            queueOperation {
                performGestureClick(clickX, clickY)
            }
        }
    }

    /**
     * 使用手势API执行点击
     */
    private fun performGestureClick(x: Float, y: Float) {
        val path = Path()
        path.moveTo(x, y)
        
        val gesture = GestureDescription.Builder()
            .addStroke(GestureDescription.StrokeDescription(path, 0, 50))
            .build()
        
        dispatchGesture(gesture, null, null)
    }

    /**
     * 构建要填写的视频描述/标题文本
     */
    private fun buildCaptionText(): String {
        val sb = StringBuilder()
        
        // 添加标题
        sb.append(videoTitle)
        
        // 如果有描述，添加描述
        if (videoDescription.isNotEmpty()) {
            sb.append("\n\n").append(videoDescription)
        }
        
        // 如果有标签，添加标签
        if (videoTags.isNotEmpty()) {
            sb.append("\n\n")
            
            // 格式化标签为抖音风格
            videoTags.split(",").forEach { tag ->
                val trimmedTag = tag.trim()
                if (trimmedTag.isNotEmpty()) {
                    sb.append("#").append(trimmedTag).append(" ")
                }
            }
        }
        
        return sb.toString()
    }

    /**
     * 获取随机延迟时间（模拟人工操作）
     */
    private fun getRandomDelay(): Long {
        return Random.nextLong(300, 1500)
    }

    /**
     * 查找描述匹配的节点
     */
    private fun findNodeByDescription(description: String): AccessibilityNodeInfo? {
        return rootInActiveWindow?.findAccessibilityNodeInfosByText(description)?.firstOrNull()
    }

    /**
     * 查找文本匹配的节点
     */
    private fun findNodeByText(text: String): AccessibilityNodeInfo? {
        return rootInActiveWindow?.findAccessibilityNodeInfosByText(text)?.firstOrNull()
    }

    /**
     * 查找提示文本匹配的节点
     */
    private fun findNodeByHint(hint: String): AccessibilityNodeInfo? {
        // 在Android的无障碍服务中，提示文本通常被视为节点的文本
        val nodes = rootInActiveWindow?.findAccessibilityNodeInfosByText(hint)
        
        // 过滤出EditText类型的节点
        return nodes?.firstOrNull { 
            it.className?.contains("EditText") == true && it.text.isNullOrEmpty() 
        }
    }

    /**
     * 查找ID匹配的节点
     */
    private fun findNodeWithId(id: String): AccessibilityNodeInfo? {
        // 注意：在Android N (API 24)及以上版本中，可以使用findAccessibilityNodeInfosByViewId
        // 但在较低版本中可能需要手动遍历
        return try {
            rootInActiveWindow?.findAccessibilityNodeInfosByViewId(id)?.firstOrNull()
        } catch (e: Exception) {
            null
        }
    }

    /**
     * 查找所有EditText节点
     */
    private fun findEditTextNodes(): List<AccessibilityNodeInfo> {
        val result = mutableListOf<AccessibilityNodeInfo>()
        findEditTextNodesRecursive(rootInActiveWindow, result)
        return result
    }

    /**
     * 递归查找EditText节点
     */
    private fun findEditTextNodesRecursive(node: AccessibilityNodeInfo?, result: MutableList<AccessibilityNodeInfo>) {
        if (node == null) return
        
        if (node.className?.contains("EditText") == true) {
            result.add(node)
        }
        
        for (i in 0 until node.childCount) {
            findEditTextNodesRecursive(node.getChild(i), result)
        }
    }

    /**
     * 显示Toast消息
     */
    private fun showToast(message: String) {
        handler.post {
            Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
        }
    }

    /**
     * 处理配置变更
     */
    override fun onInterrupt() {
        // 服务中断，复位所有状态
        updateStep(RpaStep.IDLE)
    }
} 